package cn.kgc.shiroday03.service.impl;

import cn.kgc.shiroday03.commons.CodeMsg;
import cn.kgc.shiroday03.commons.ResponseResult;
import cn.kgc.shiroday03.dto.UserFormDTO;
import cn.kgc.shiroday03.dto.UserPageDTO;
import cn.kgc.shiroday03.entity.*;
import cn.kgc.shiroday03.mapper.*;
import cn.kgc.shiroday03.service.UserService;
import cn.kgc.shiroday03.util.SaltUtil;
import cn.kgc.shiroday03.util.TreeUtil;
import cn.kgc.shiroday03.vo.PermissionVO;
import cn.kgc.shiroday03.vo.UserVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 */
@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RoleMapper  roleMapper;

    @Autowired
    private RolePersMapper rolePersMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public ResponseResult getPage(UserPageDTO userPageDTO) {

        Page<User> userPage = new Page<>(userPageDTO.getPage(), userPageDTO.getLimit());
        // 创建分页的查询条件
        LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();
        String city = userPageDTO.getCity();
        String username = userPageDTO.getUsername();
        //  mp  动态sql
        lambda.like((!ObjectUtils.isEmpty(city) && !"".equals(city)), User::getCity, userPageDTO.getCity())
                .like((!ObjectUtils.isEmpty(username) && !"".equals(username)), User::getUsername, userPageDTO.getUsername());
        /**
         * username  city
         *   select  *  from user  where username = ?  limit
         *   select  *  from user  where city = ?  limit
         *   select  *  from user  where username = ?  and  city = ?  limit
         *   select  *  from user  limit
         */
        userMapper.selectPage(userPage, lambda);

        // 通过userPage获取分页数据
        List<User> users = userPage.getRecords();
        //  分页数据的总条数
        long total = userPage.getTotal();

        List<UserVO> userVOS = users.stream().map(user -> {
            UserVO userVO = new UserVO();
            // 对象属性的拷贝
            BeanUtils.copyProperties(user,userVO);

            //获取用户的id  查询用户拥有的角色id    user_role
            Integer userId = user.getId();
            QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
            userRoleQueryWrapper.eq("user_id", userId);

            List<UserRole> userRoles = userRoleMapper.selectList(userRoleQueryWrapper);
            List<Integer> roleIds = userRoles.stream().map(userRole -> userRole.getRoleId()).collect(Collectors.toList());
            // 根据角色id  查询角色信息
            List<Role> roles = roleMapper.selectBatchIds(roleIds);
            List<String> roleNames = roles.stream().map(role -> role.getComments()).collect(Collectors.toList());
            userVO.setRoles(roleNames);
            return userVO;
        }).collect(Collectors.toList());

        return new ResponseResult(CodeMsg.SUCCESS, total,userVOS);
    }

    @Override
    public ResponseResult addUser(UserFormDTO userFormDTO) {
        User user = new User();
        BeanUtils.copyProperties(userFormDTO,user);
        // 获取随机盐
        String salt = SaltUtil.getSalt(5);
        Md5Hash md5Hash = new Md5Hash("888888", salt, 20);
        String s = md5Hash.toHex();
        user.setPassword(s);
        user.setSalt(salt);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username",user.getUsername());
        // 判定用户名 是否已被占用
        User usr = userMapper.selectOne(userQueryWrapper);

        if(!ObjectUtils.isEmpty(usr)){
            return  new ResponseResult(CodeMsg.USER_EXIST);
        }
        // 添加用户信息到用户表
        userMapper.insert(user);
        List<Integer> roleIds = userFormDTO.getRoleIds();
        Integer userId = user.getId();
        //  userId  roleId    userRole  -> user_role
        roleIds.forEach(rid ->{
            UserRole userRole = new UserRole();
            userRole.setRoleId(rid);
            userRole.setUserId(userId);
            userRoleMapper.insert(userRole);
        });

        return new ResponseResult(CodeMsg.SUCCESS);
    }

    @Override
    public ResponseResult getUserById(Integer id) {

        //  1. 根据用户的id  查询用户信息

        User user = userMapper.selectById(id);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user,userVO);

        // 2. 根据用户的id  查询用户的角色id
        LambdaQueryWrapper<UserRole> lambda= new LambdaQueryWrapper<>();
        lambda.eq(UserRole::getUserId,id);
        List<UserRole> userRoles = userRoleMapper.selectList(lambda);
        List<Integer> roleIds = userRoles.stream().map(ur -> ur.getRoleId()).collect(Collectors.toList());
        userVO.setRoleIds(roleIds);

        return new ResponseResult(CodeMsg.SUCCESS,null,userVO);
    }

    @Override
    public ResponseResult updateUser(UserFormDTO userFormDTO) {

        //  1.  userFormDTO  ->  user  user_role
        User user = new User();
        BeanUtils.copyProperties(userFormDTO,user);

        //更新用户信息
        userMapper.updateById(user);

        // 用户最新的角色id
        List<Integer> roleIds = userFormDTO.getRoleIds();

        // 更新用户角色信息   user_role
        LambdaQueryWrapper<UserRole> lambda = new LambdaQueryWrapper<>();
        Integer id = userFormDTO.getId();
        lambda.eq(UserRole::getUserId, id);
        //  1. 根据用户的id  删除user_role表中的角色id
        userRoleMapper.delete(lambda);

        // 2. 将前端传入的最新的角色id写入user_role
        roleIds.forEach(roleId->{
            UserRole userRole = new UserRole();
            userRole.setUserId(id);
            userRole.setRoleId(roleId);
            // 将角色信息插入数据库
            userRoleMapper.insert(userRole);
        });

        return new ResponseResult(CodeMsg.SUCCESS);
    }

    @Override
    public ResponseResult deleteById(Integer[] ids) {

        //1. 根据用户的id  删除用户信息  user
        userMapper.deleteBatchIds(Arrays.asList(ids));
        
        // 2. 根据用户id  删除用户的角色信息  user_role
        LambdaQueryWrapper<UserRole> lambda = new LambdaQueryWrapper<>();
        lambda.in(UserRole::getUserId,Arrays.asList(ids));
        userRoleMapper.delete(lambda);

        return new ResponseResult(CodeMsg.SUCCESS);
    }

    @Override
    public Map<String, Object> loadMenu(String username) {

        //  1. 创建菜单集合
        HashMap<String, Object> menu = new HashMap<>();
        //  homeInfo    home 集合  存储 首页信息   "title": "首页","href": "https://www.8zt.cc"
        HashMap<String, Object> home = new HashMap<>();
        home.put("title","首页");
        home.put("href","https://www.8zt.cc");
        menu.put("homeInfo",home);


       /* logoInfo  log
            "title": "KGC",
            "image": "/dist/images/logo.png",
            "href": ""
       */
        HashMap<String, Object> logo = new HashMap<>();
        logo.put("title","KGC");
        logo.put("href","https://www.kgc.cn");
        logo.put("image","/dist/images/logo.png");
        menu.put("logoInfo",logo);


        //  用户的权限信息进行封装  menuInfo    list   username
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getUsername,username);
        User user = userMapper.selectOne(userLambdaQueryWrapper);
        // 获取用户id
        Integer userId = user.getId();
        // 根据用户的id 查询用户角色id  user_role
        LambdaQueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<UserRole>().lambda();
        userRoleQueryWrapper.eq(UserRole::getUserId,userId);
        List<UserRole> userRoles = userRoleMapper.selectList(userRoleQueryWrapper);
        List<Integer> rids = userRoles.stream().map(ur -> ur.getRoleId()).collect(Collectors.toList());

        // 根据角色的id 查询角色的权限id  role_permission
        LambdaQueryWrapper<RolePers> rolePersLambdaQueryWrapper = new LambdaQueryWrapper<>();
        rolePersLambdaQueryWrapper.in(RolePers::getRoleId,rids);
        List<RolePers> rolePers = rolePersMapper.selectList(rolePersLambdaQueryWrapper);
        List<Integer> pids = rolePers.stream().map(rp -> rp.getPerId())
                .distinct()
                .collect(Collectors.toList());

        // 根据 权限id查询权限详细信息
        List<Permission> permissions = permissionMapper.selectBatchIds(pids).stream().filter(p -> p.getIsMenu()!= 2).collect(Collectors.toList());

        //  将  Permission  ->PermissionVO

        List<PermissionVO> permissionVOS = permissions.stream().map(p -> {
            PermissionVO permissionVO = new PermissionVO();
            BeanUtils.copyProperties(p, permissionVO);
            String icon = permissionVO.getIcon();
            // 处理图标显示问题
            permissionVO.setIcon("layui-icon "+icon);
            return  permissionVO;
        }).collect(Collectors.toList());


        List<PermissionVO> permissionVOS1 = TreeUtil.toTree(permissionVOS, 0);
        System.out.println("permissionVOS1 = " + permissionVOS1);

        menu.put("menuInfo",permissionVOS1);

        return menu;
    }
}




